﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Client
{
    public partial class Form1 : Form
    {
        Socket socket;
        Thread receiveThread;
        byte[] packet;

        public Form1()
        {
            InitializeComponent();
        }

        #region GUI metody
        
        /// <summary>
        /// Pripoji klienta k serveru.
        /// </summary>
        private void connectButton_Click(object sender, EventArgs e)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect(new IPEndPoint(IPAddress.Loopback, 5000));

            packet = new byte[1024];

            // prijmeme inicialni data boje
            socket.Receive(packet);

            // dekodujeme data z bufferu
            LoadStatus(packet);

            
        }


        private void attackButton_Click(object sender, EventArgs e)
        {
            if (actions1ListBox.SelectedIndex == -1)
                MessageBox.Show("You need to choose a Jutsu!");
            else
            {
                byte[] b = new byte[1];
                b = Encoding.ASCII.GetBytes(actions1ListBox.SelectedIndex.ToString());
                socket.Send(b);

                Receive();

                receiveThread.Join();

                UpdateHP(packet);
            }
        }

        #endregion

        #region Ostatni metody

        /// <summary>
        /// Vytvori novy thread, ve kterem bude cekat na data ze serveru.
        /// </summary>
        private void Receive()
        {
            packet = new byte[1024];
            
            receiveThread = new Thread(Listen);

            receiveThread.Start();
        }

        /// <summary>
        /// Posloucha v oddelenem vlakne na receive dat ze serveru.
        /// </summary>
        private void Listen()
        {
            try
            {
                socket.Receive(packet);
            }
            catch (Exception ex)
            {
                logTextBox.AppendText(ex.Message + "\n");
            }
        }

        /// <summary>
        /// Dekoduje inicialni stav boje a updatuje info ve formu.
        /// </summary>
        /// <param name="packet">Prijaty stav boje ze serveru.</param>
        private void LoadStatus(byte[] packet)
        {
            string s = GetString(packet);

            char[] sep = new char[] { ';' };
            string[] tokens = s.Split(sep, StringSplitOptions.RemoveEmptyEntries);

            hp1TextBox.Text = tokens[0].Substring(tokens[0].IndexOf(":") + 1);
            hp2TextBox.Text = tokens[1].Substring(tokens[1].IndexOf(":") + 1);
            
            actions1ListBox.Items.Add(tokens[2].Substring(tokens[2].IndexOf(":") + 1));
            actions1ListBox.Items.Add(tokens[3].Substring(tokens[3].IndexOf(":") + 1));

            logTextBox.AppendText(tokens[4].Substring(tokens[4].IndexOf(":") + 1) + "\n");
        }

        /// <summary>
        /// Prepise HP obou hracu.
        /// </summary>
        /// <param name="packet"></param>
        private void UpdateHP(byte[] packet)
        {
            string s = GetString(packet);

            char[] sep = new char[] { ';' };
            string[] tokens = s.Split(sep, StringSplitOptions.RemoveEmptyEntries);

            hp1TextBox.Text = tokens[0].Substring(tokens[0].IndexOf(":") + 1);
            hp2TextBox.Text = tokens[1].Substring(tokens[1].IndexOf(":") + 1);
        }

        /// <summary>
        /// Dekoduje paket na string.
        /// </summary>
        private string GetString(byte[] packet)
        {
            int i = 0;
            while (packet[i] > 0)
                i++;

            string s = Encoding.ASCII.GetString(packet, 0, i);
            return s;
        }

        #endregion

    }
}
